#pragma once
#include<iostream>
#include<queue>
#include<pthread.h>

template<class T>
class BlcokQueue
{
    static const int defalutnum = 20;
public:
    BlcokQueue(int maxcap = defalutnum)
        :_maxcap(maxcap)
    {
        pthread_mutex_init(&_mutex);
        pthread_cond_init(&full);
        pthread_cond_init(&empty);
    }
    ~BlockQueue()
    {
        pthread_mutex_destory(&_mutex);
        pthread_cond_destory(&full);
        pthread_cond_destory(&empty);
    }

    T Pop()
    {
        pthread_mutex_lock(&_mutex);
        while (_taskqueue.size() == 0)
        {
            pthread_cond_wait(&_empty, &_mutex);
        }
        T task = _taskqueue.front();
        _taskqueue.pop();
        pthread_cond_signal(&full);
        pthread_mutex_unlock(&_mutex);
        return task;
    }

    void Push(const T& task)
    {
        pthrad_mutex_lock(&_mutex);
        while (_taskqueue.size == _maxcap)
        {
            pthread_cond_wait(&full, _mutex);
        }
        _taskqueue.push(task);
        pthread_cond_signal(&empty);
        pthrad_mutex_unlock();
    }

private:
    std::queue<T> _taskqueue;
    int _maxcap;
    pthread_mutex_t _mutex;
    pthread_cond_t _full;
    pthread_cond_t _empty;

};